package com.yida.wy.basic.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.PhoneUtil;
import com.mybatisflex.core.query.QueryWrapper;
import com.yida.common.core.exception.ServiceException;
import com.yida.common.core.utils.StringUtils;
import com.yida.common.core.utils.file.FileTypeUtils;
import com.yida.common.core.web.domain.AjaxResult;
import com.yida.common.core.web.page.TableDataInfo;
import com.yida.common.log.annotation.Log;
import com.yida.common.log.enums.BusinessType;
import com.yida.common.security.annotation.RequiresPermissions;
import com.yida.common.security.utils.SecurityUtils;
import com.yida.wy.basic.domain.dto.WyImpBuildListDTO;
import com.yida.wy.basic.domain.dto.WyImpCommunityListDTO;
import com.yida.wy.basic.domain.dto.WyImpHouseOwnerListDTO;
import com.yida.wy.basic.domain.request.WyImpBuildListRequest;
import com.yida.wy.basic.domain.request.WyImpCommunityListRequest;
import com.yida.wy.basic.domain.request.WyImpHouseOwnerListRequest;
import com.yida.wy.basic.service.IWyImpBasicDataService;
import com.yida.wy.common.constant.WyConstants;
import com.yida.wy.common.constant.WyCustomImportConstants;
import com.yida.wy.common.domain.WyBaseBuild;
import com.yida.wy.common.domain.WyBaseCommunity;
import com.yida.wy.common.domain.WyBaseHouse;
import com.yida.wy.common.domain.WyBaseOwner;
import com.yida.wy.common.domain.request.WyBaseBuildAddUpdateRequest;
import com.yida.wy.common.domain.request.WyBaseCommunityAddUpdateRequest;
import com.yida.wy.common.domain.request.WyBaseHouseOwnerAddUpdateRequest;
import com.yida.wy.common.service.IWyBaseBuildService;
import com.yida.wy.common.service.IWyBaseCommunityService;
import com.yida.wy.common.service.IWyBaseHouseService;
import com.yida.wy.common.service.IWyBaseOwnerService;
import com.yida.wy.common.valid.Save;
import com.yida.wy.common.valid.Update;
import com.yida.wy.common.web.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;

import static com.yida.wy.common.domain.table.WyBaseBuildTableDef.WY_BASE_BUILD;
import static com.yida.wy.common.domain.table.WyBaseCommunityTableDef.WY_BASE_COMMUNITY;
import static com.yida.wy.common.domain.table.WyBaseHouseTableDef.WY_BASE_HOUSE;
import static com.yida.wy.common.domain.table.WyBaseOwnerTableDef.WY_BASE_OWNER;

/**
 * 自定义导入
 *
 * @author lqq
 * @date 2023-11-21
 */
@Api(tags = "导入楼盘")
@RestController
@RequestMapping("/imp")
public class WyImpBasicDataController extends BaseController {

    @Resource
    private IWyImpBasicDataService impBasicDataService;

    @Resource
    private IWyBaseCommunityService communityService;

    @Resource
    private IWyBaseBuildService buildService;

    @Resource
    private IWyBaseHouseService houseService;

    @Resource
    private IWyBaseOwnerService ownerService;

    /**
     * 查询基础小区列表(根据小区名称)
     */
    @GetMapping("/communityList")
    @RequiresPermissions("wy:basic:imp:community:list")
    @ApiOperation(value = "查询小区列表", response = WyImpCommunityListDTO.class)
    public TableDataInfo list(@Validated WyImpCommunityListRequest request) {
        //查询导入的项目数据
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.where(WY_BASE_COMMUNITY.IMPORT_FLAG.eq(WyConstants.YES))
                .and(WY_BASE_COMMUNITY.AREA_ID.eq(request.getAreaId()))
                .and(WY_BASE_COMMUNITY.COMMUNITY_NAME.like(request.getCommunityName()))
                .and(WY_BASE_COMMUNITY.COMMUNITY_ID.like(request.getCommunityId()));
        return getDataTable(communityService.basicPageAs(request.getPageNum(), request.getPageSize(), wrapper, WyImpCommunityListDTO.class));
    }

    /**
     * 新增小区
     */
    @PostMapping("/community")
    @ApiOperation(value = "新增小区")
    @RequiresPermissions("wy:basic:imp:community:add")
    @Log(title = "导入楼盘-新增小区", businessType = BusinessType.INSERT)
    public AjaxResult communityAdd(@Validated(Save.class) @RequestBody WyBaseCommunityAddUpdateRequest request) {
        if (communityService.count(QueryWrapper.create().where(WY_BASE_COMMUNITY.COMMUNITY_NAME.eq(request.getCommunityName()))) > 0) {
            return AjaxResult.error("新增失败，小区名称已存在！");
        }
        WyBaseCommunity community = BeanUtil.copyProperties(request, WyBaseCommunity.class);
        community.setImportFlag(WyConstants.YES);
        if (request.getOutsideFlag()) {
            community.setCreateBy(SecurityUtils.getLoginUser().getSysOutsideUser().getRealName());
        } else {
            community.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
        }
        return toAjax(communityService.save(community));
    }

    /**
     * 修改小区
     */
    @PutMapping("/community")
    @ApiOperation(value = "修改小区")
    @RequiresPermissions("wy:basic:imp:community:edit")
    @Log(title = "导入楼盘-修改小区", businessType = BusinessType.UPDATE)
    public AjaxResult communityEdit(@Validated(Update.class) @RequestBody WyBaseCommunityAddUpdateRequest request) {
        WyBaseCommunity baseCommunity = communityService.getById(request.getCommunityId());
        if (!baseCommunity.getCommunityName().equals(request.getCommunityName()) && communityService.count(QueryWrapper.create().where(WY_BASE_COMMUNITY.COMMUNITY_NAME.eq(request.getCommunityName()))) > 0) {
            return AjaxResult.error("修改失败，小区名称已存在！");
        }
        if (request.getOutsideFlag()) {
            request.setUpdateBy(SecurityUtils.getLoginUser().getSysOutsideUser().getRealName());
        } else {
            request.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
        }
        return toAjax(communityService.updateById(BeanUtil.copyProperties(request, WyBaseCommunity.class)));
    }

    /**
     * 小区详情
     */
    @RequiresPermissions("wy:basic:imp:community:query")
    @GetMapping(value = "/community/{id}")
    @ApiOperation(value = "小区详情", response = WyBaseCommunity.class)
    public AjaxResult getCommunityInfo(@PathVariable("id") Long id) {
        return AjaxResult.success(communityService.getById(id));
    }

    /**
     * 批量删除小区
     */
    @ApiOperation(value = "批量删除小区")
    @DeleteMapping("/removeCommunitys/{communityIds}")
    @RequiresPermissions("wy:basic:imp:community:remove")
    @Log(title = "导入楼盘-批量删除小区", businessType = BusinessType.DELETE)
    public AjaxResult removeCommunitys(@PathVariable Long[] communityIds) {
        for (Long communityId : communityIds) {
            if (buildService.count(QueryWrapper.create().where(WY_BASE_BUILD.COMMUNITY_ID.eq(communityId))) > 0) {
                throw new ServiceException("编号：[" + communityId + "]项目下存在楼栋，请先删除楼栋后再操作！");
            }
        }
        return toAjax(communityService.removeByIds(ListUtil.toList(communityIds)));
    }

    /**
     * 小区项目导入
     */
    @ApiOperation(value = "项目导入")
    @PostMapping("/importDataCommunity")
    @RequiresPermissions("wy:basic:imp:community:import")
    @Log(title = "导入楼盘-项目导入", businessType = BusinessType.IMPORT)
    public AjaxResult importDataCommunity(MultipartFile file, @RequestParam(name = "updateSupport") boolean updateSupport, @RequestParam(name = "outsideFlag") boolean outsideFlag) throws Exception {
        if (file.isEmpty()) {
            return AjaxResult.error("导入项目文件不能为空！");
        }
        if (!checkImportFile(file)) {
            return AjaxResult.error("不是指定的xlsx，xls导入类型文件！");
        }
        String message = impBasicDataService.importBaseCommunity(file, updateSupport, outsideFlag);
        return AjaxResult.success(message);
    }

    /*************************************************小区end**************************************************/
    /**
     * 查询基础楼栋列表(根据小区ID)
     */
    @GetMapping("/buildList")
    @RequiresPermissions("wy:basic:imp:build:list")
    @ApiOperation(value = "查询楼栋列表", response = WyImpBuildListDTO.class)
    public TableDataInfo list(WyImpBuildListRequest request) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.where(WY_BASE_BUILD.COMMUNITY_ID.eq(request.getCommunityId()))
                .and(WY_BASE_BUILD.BUILD_NAME.like(request.getBuildName()));
        return getDataTable(buildService.basicPageAs(request.getPageNum(), request.getPageSize(), wrapper, WyImpBuildListDTO.class));
    }

    /**
     * 新增楼栋
     */
    @PostMapping("/build")
    @ApiOperation(value = "新增楼栋")
    @RequiresPermissions("wy:basic:imp:build:add")
    @Log(title = "导入楼盘-新增楼栋", businessType = BusinessType.INSERT)
    public AjaxResult buildAdd(@Validated(Save.class) @RequestBody WyBaseBuildAddUpdateRequest request) {
        if (buildService.count(QueryWrapper.create().where(WY_BASE_BUILD.BUILD_NAME.eq(request.getBuildName()).and(WY_BASE_BUILD.COMMUNITY_ID.eq(request.getCommunityId())))) > 0) {
            return AjaxResult.error("新增失败，同小区下楼栋名称已存在！");
        }
        WyBaseBuild build = BeanUtil.copyProperties(request, WyBaseBuild.class);
        build.setImportFlag(WyConstants.YES);
        if (request.getOutsideFlag()) {
            build.setCreateBy(SecurityUtils.getLoginUser().getSysOutsideUser().getRealName());
        } else {
            build.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
        }
        build.setProjectCode(WyCustomImportConstants.SELFBUILTHOUSES + request.getCommunityId());
        return toAjax(impBasicDataService.savBuild(build));
    }

    /**
     * 楼栋详情
     */
    @RequiresPermissions("wy:basic:imp:build:query")
    @GetMapping(value = "/build/{id}")
    @ApiOperation(value = "楼栋详情", response = WyBaseBuild.class)
    public AjaxResult getBuildInfo(@PathVariable("id") Long id) {
        return AjaxResult.success(buildService.getById(id));
    }

    /**
     * 修改楼栋
     */
    @PutMapping("/build")
    @RequiresPermissions("wy:basic:imp:build:edit")
    @Log(title = "导入楼盘-修改楼栋", businessType = BusinessType.UPDATE)
    @ApiOperation(value = "修改楼栋")
    public AjaxResult buildEdit(@Validated(Update.class) @RequestBody WyBaseBuildAddUpdateRequest request) {
        WyBaseBuild baseBuild = buildService.getById(request.getBuildId());
        if (!baseBuild.getBuildName().equals(request.getBuildName()) &&
                buildService.count(QueryWrapper.create().where(WY_BASE_BUILD.BUILD_NAME.eq(request.getBuildName()).and(WY_BASE_BUILD.COMMUNITY_ID.eq(request.getCommunityId())))) > 0) {
            return AjaxResult.error("修改失败，同小区下楼栋名称已存在！");
        }
        if (request.getOutsideFlag()) {
            request.setUpdateBy(SecurityUtils.getLoginUser().getSysOutsideUser().getRealName());
        } else {
            request.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
        }
        return toAjax(buildService.updateById(BeanUtil.copyProperties(request, WyBaseBuild.class)));
    }

    /**
     * 批量删除楼栋
     */
    @ApiOperation(value = "批量删除楼栋")
    @DeleteMapping("/removeBuilds/{buildCodes}")
    @RequiresPermissions("wy:basic:imp:build:remove")
    @Log(title = "导入楼盘-批量删除楼栋", businessType = BusinessType.DELETE)
    public AjaxResult removeBuilds(@PathVariable String[] buildCodes) {
        for (String buildCode : buildCodes) {
            if (houseService.count(QueryWrapper.create().where(WY_BASE_HOUSE.BUILD_CODE.eq(buildCode))) > 0) {
                throw new ServiceException("编号：[" + buildCode + "]楼栋下存在房屋，请先删除房屋后再操作！");
            }
        }
        return toAjax(buildService.remove(QueryWrapper.create().where(WY_BASE_BUILD.BUILD_CODE.in(buildCodes))));
    }

    /**
     * 楼栋导入
     */
    @ApiOperation(value = "楼栋导入")
    @PostMapping("/importDataBuild")
    @RequiresPermissions("wy:basic:imp:build:import")
    @Log(title = "导入楼盘-楼栋导入", businessType = BusinessType.IMPORT)
    public AjaxResult importDataBuild(MultipartFile file, @RequestParam(name = "updateSupport") boolean updateSupport, @RequestParam(name = "communityId") Long communityId, @RequestParam(name = "outsideFlag") boolean outsideFlag) throws Exception {
        if (file.isEmpty()) {
            return AjaxResult.error("导入楼栋文件不能为空！");
        }
        if (!checkImportFile(file)) {
            return AjaxResult.error("不是指定的xlsx，xls导入类型文件！");
        }
        String message = impBasicDataService.importDataBuild(file, updateSupport, communityId, outsideFlag);
        return AjaxResult.success(message);
    }

    /*************************************************楼栋end**************************************************/

    /**
     * 根据条件查询房屋信息
     */
    @GetMapping("/houseOwnerList")
    @RequiresPermissions("wy:basic:imp:houseOwner:list")
    @ApiOperation(value = "查询房屋业主列表", response = WyImpHouseOwnerListDTO.class)
    public TableDataInfo queryHouseListByParam(WyImpHouseOwnerListRequest request) {
        QueryWrapper wrapper = QueryWrapper.create()
                .select(WY_BASE_OWNER.ALL_COLUMNS)
                .select(WY_BASE_HOUSE.ALL_COLUMNS)
                .select(WY_BASE_BUILD.BUILD_NAME, WY_BASE_BUILD.UNIT_TOTAL)
                .from(WY_BASE_OWNER)
                .leftJoin(WY_BASE_HOUSE).on(WY_BASE_OWNER.HOUSE_CODE.eq(WY_BASE_HOUSE.HOUSE_CODE))
                .leftJoin(WY_BASE_BUILD).on(WY_BASE_HOUSE.BUILD_CODE.eq(WY_BASE_BUILD.BUILD_CODE))
                .where(WY_BASE_HOUSE.BUILD_CODE.eq(request.getBuildCode())
                        .and(WY_BASE_HOUSE.ROOM_NUM.eq(request.getRoomNum()))
                        .and(WY_BASE_OWNER.OWNER_NAME.eq(request.getOwnerName())));
        return getDataTable(ownerService.basicPageAs(request.getPageNum(), request.getPageSize(), wrapper, WyImpHouseOwnerListDTO.class));
    }

    /**
     * 新增房屋业主
     */
    @PostMapping("/houseOwner")
    @ApiOperation(value = "新增房屋业主")
    @RequiresPermissions("wy:basic:imp:houseOwner:add")
    @Log(title = "导入楼盘-新增房屋业主", businessType = BusinessType.INSERT)
    public AjaxResult houseOwnerAdd(@Validated(Save.class) @RequestBody WyBaseHouseOwnerAddUpdateRequest request) {
        if (StringUtils.isNotBlank(request.getOwner().getCardNum()) && !IdcardUtil.isValidCard(request.getOwner().getCardNum())) {
            return AjaxResult.error("新增失败，业主身份证格式不正确！");
        }
        if (StringUtils.isNotBlank(request.getOwner().getOwnerPhone()) && !PhoneUtil.isPhone(request.getOwner().getOwnerPhone())) {
            return AjaxResult.error("新增失败，业主手机号码格式不正确！");
        }
        if (houseService.count(QueryWrapper.create().where(WY_BASE_HOUSE.ROOM_NUM.eq(request.getHouse().getRoomNum()).and(WY_BASE_HOUSE.BUILD_CODE.eq(request.getHouse().getBuildCode())))) > 0) {
            return AjaxResult.error("新增失败，同楼栋下房牌号已存在！");
        }
        WyBaseHouse house = BeanUtil.copyProperties(request.getHouse(), WyBaseHouse.class);
        WyBaseOwner owner = BeanUtil.copyProperties(request.getOwner(), WyBaseOwner.class);
        if (request.getOutsideFlag()) {
            house.setCreateBy(SecurityUtils.getLoginUser().getSysOutsideUser().getRealName());
            owner.setCreateBy(SecurityUtils.getLoginUser().getSysOutsideUser().getRealName());
        } else {
            house.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
            owner.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
        }
        return toAjax(impBasicDataService.saveHouseOwner(house, owner));
    }

    /**
     * 房屋业主详情
     */
    @RequiresPermissions("wy:basic:imp:houseOwner:query")
    @GetMapping(value = "/houseOwner/{houseId}/{ownerId}")
    @ApiOperation(value = "房屋业主详情")
    public AjaxResult getHouseOwnerInfo(@PathVariable("houseId") Long houseId, @PathVariable("ownerId") Long ownerId) {
        AjaxResult result = AjaxResult.success();
        result.put("house", houseService.getById(houseId));
        result.put("owner", ownerService.getById(ownerId));
        return result;
    }

    /**
     * 修改房屋业主
     */
    @PutMapping("/houseOwner")
    @ApiOperation(value = "修改房屋业主")
    @RequiresPermissions("wy:basic:imp:houseOwner:edit")
    @Log(title = "导入楼盘-修改房屋业主", businessType = BusinessType.UPDATE)
    public AjaxResult houseOwnerEdit(@Validated(Update.class) @RequestBody WyBaseHouseOwnerAddUpdateRequest request) {
        if (StringUtils.isNotBlank(request.getOwner().getCardNum()) && !IdcardUtil.isValidCard(request.getOwner().getCardNum())) {
            return AjaxResult.error("修改失败，业主身份证格式不正确！");
        }
        if (StringUtils.isNotBlank(request.getOwner().getOwnerPhone()) && !PhoneUtil.isPhone(request.getOwner().getOwnerPhone())) {
            return AjaxResult.error("修改失败，业主手机号码格式不正确！");
        }
        WyBaseHouse wyBaseHouse = houseService.getById(request.getHouse().getHouseId());
        if (!wyBaseHouse.getRoomNum().equals(request.getHouse().getRoomNum()) &&
                houseService.count(QueryWrapper.create().where(WY_BASE_HOUSE.ROOM_NUM.eq(request.getHouse().getRoomNum()).and(WY_BASE_HOUSE.BUILD_CODE.eq(request.getHouse().getBuildCode())))) > 0) {
            return AjaxResult.error("修改失败，同楼栋下房牌号已存在！");
        }
        WyBaseHouse house = BeanUtil.copyProperties(request.getHouse(), WyBaseHouse.class);
        WyBaseOwner owner = BeanUtil.copyProperties(request.getOwner(), WyBaseOwner.class);
        if (request.getOutsideFlag()) {
            house.setUpdateBy(SecurityUtils.getLoginUser().getSysOutsideUser().getRealName());
            owner.setUpdateBy(SecurityUtils.getLoginUser().getSysOutsideUser().getRealName());
        } else {
            house.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
            owner.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
        }
        return toAjax(impBasicDataService.updateHouseOwner(house, owner));
    }

    /**
     * 批量删除房屋业主
     */
    @ApiOperation(value = "批量删除房屋业主")
    @DeleteMapping("/removeHouses/{houseCodes}")
    @RequiresPermissions("wy:basic:imp:houseOwner:remove")
    @Log(title = "导入楼盘-批量删除房屋业主", businessType = BusinessType.DELETE)
    public AjaxResult removeHouses(@PathVariable String[] houseCodes) {
        return toAjax(impBasicDataService.removeHouseOwnerByHouseCodes(houseCodes));
    }

    /**
     * 20230802修订
     *
     * @param file          文件类型
     * @param updateSupport 是否更新
     * @param areaId        地区ID
     * @param buildCode     楼栋标识码
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "房屋导入")
    @PostMapping("/importDataHouse")
    @RequiresPermissions("wy:basic:imp:houseOwner:import")
    @Log(title = "导入楼盘-房屋导入", businessType = BusinessType.IMPORT)
    public AjaxResult importDataHouse(MultipartFile file, @RequestParam(name = "updateSupport") boolean updateSupport, @RequestParam(name = "areaId") Long areaId, @RequestParam(name = "buildCode") String buildCode, @RequestParam(name = "outsideFlag") boolean outsideFlag) throws Exception {
        if (!checkImportFile(file)) {
            return AjaxResult.error("不是指定的xlsx，xls导入类型文件！");
        }
        String message = impBasicDataService.importDataHouseAndOwner(file, updateSupport, areaId, buildCode, outsideFlag);
        return AjaxResult.success(message);
    }
    /*************************************************房屋、业主end**************************************************/

    /**
     * 检测导入文件类型是否合规
     *
     * @param file
     * @return
     * @throws IOException
     * @throws IORuntimeException
     */
    /**
     * 检测导入文件类型是否合规
     *
     * @param file 文件
     * @return /
     */
    private boolean checkImportFile(MultipartFile file) {
        // 检查文件类型
        String type = FileTypeUtils.getExtension(file);
        // 限制的文件类型集合
        return StringUtils.inStringIgnoreCase(type, "xlsx", "xls");
    }
}
